
import java.io.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Stack;
import java.util.Random;
import java.lang.Math;
import java.lang.String;


class Player{
	private String name;
	private int emotionalState;
	private LinkedList<Card> holeCards;
	private LinkedList<Hand> currentHands;
	private int money;
	private int currentBet;
	private boolean hasFolded;
	private boolean hasBet;
	private boolean handUpdated;
	private Hand bestHand;
	protected boolean hasRaised;
	protected boolean hasActed;
	public String type;
	
	public Player(){
		this.name = "dne";
		this.type = "human";
	}
	
	public Player( String n ){
		this.name = n;
		this.type = "human";
		this.emotionalState = 5;
		this.holeCards = new LinkedList<Card>();
		this.money = 200;
		this.currentBet = 0;
		this.hasFolded = false;
		this.hasBet = false;
		currentHands = new LinkedList<Hand>();
	}
	public void setName(String n)
	{
		name = n;
	}
	public String act(String[] validActions, int lastCurrBet) throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String s;
		int userInput = 0;
		int bet=0;
		System.out.println("\nPlayer " + this.name);
		System.out.println("Your cards are: " + toStringHoleCards());
		System.out.println("Current bet is: " + lastCurrBet);
		System.out.println("Current cash is: " + money);
		System.out.println("Choose an action");
		for(int i=0; i<validActions.length; i++)
		{
			//Display valid actions			
			System.out.println("  (" + i + ")" + validActions[i]);
		}
		s = br.readLine();
		userInput = Integer.parseInt(s);
		if(validActions[userInput] == "raise" && hasRaised)
		{
			userInput = 1;
		}
		if( validActions[userInput] == "bet" ){
			System.out.println("How much would you like to bet");
			s = br.readLine();
			bet = Integer.parseInt(s);
			currentBet = bet; 
		}
		if( validActions[userInput] == "raise"){
			System.out.println("How much would you like to raise by");
			s = br.readLine();
			bet = Integer.parseInt(s);
			hasRaised = true;
			//// vincnet removed .. it was here twice
			currentBet = bet + lastCurrBet;
		}
		if( validActions[userInput] == "call" )
		{
			currentBet = lastCurrBet; 
		}
		//Take user input as an int which represents which valid action they choose
		hasActed = true;
		return validActions[userInput];	
	}
	private Hand calcBestHand()
	{
		Hand temp = currentHands.get(0);
		for(int i=1; i<currentHands.size(); i++)
		{
			if (temp.compareTo(currentHands.get(i)) < 0)
			{
				temp = currentHands.get(i);
			}
		}
		return temp;
	}
	public void calcPossibleHands(LinkedList<Card> commCards)
	{
		int numCommCards = commCards.size();
		for(int i=0; i<currentHands.size(); i++)
		{
			currentHands.remove();
		}
		if(commCards.size() < 3)
		{
			return;
		}
		LinkedList<Card> myCards = new LinkedList<Card>();
		Card[] temp = new Card[5];
		for(int i=0; i<2; i++)
		{
			myCards.add(holeCards.get(i));
		}
		for(int i=0; i<commCards.size(); i++)
		{
			myCards.add(commCards.get(i));
		}		
		if(numCommCards >= 3)
		{
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(2);
			temp[3] = myCards.get(3);
			temp[4] = myCards.get(4);
			currentHands.add(new Hand(temp));
		}
		if(numCommCards >= 4)
		{			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(2);
			temp[3] = myCards.get(3);
			temp[4] = myCards.get(5);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(2);
			temp[3] = myCards.get(4);
			temp[4] = myCards.get(5);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(4);
			temp[4] = myCards.get(5);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(2);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(4);
			temp[4] = myCards.get(5);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(1);
			temp[1] = myCards.get(2);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(4);
			temp[4] = myCards.get(5);
			currentHands.add(new Hand(temp));
		}
		if(numCommCards >= 5)
		{
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(2);
			temp[3] = myCards.get(3);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(2);
			temp[3] = myCards.get(4);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(2);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(4);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(1);
			temp[2] = myCards.get(4);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(2);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(2);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(4);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(2);
			temp[2] = myCards.get(4);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(0);
			temp[1] = myCards.get(3);
			temp[2] = myCards.get(4);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(1);
			temp[1] = myCards.get(2);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(4);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(1);
			temp[1] = myCards.get(2);
			temp[2] = myCards.get(3);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(1);
			temp[1] = myCards.get(2);
			temp[2] = myCards.get(4);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(1);
			temp[1] = myCards.get(3);
			temp[2] = myCards.get(4);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
			
			temp[0] = myCards.get(2);
			temp[1] = myCards.get(3);
			temp[2] = myCards.get(4);
			temp[3] = myCards.get(5);
			temp[4] = myCards.get(6);
			currentHands.add(new Hand(temp));
		}
	}
	public void fold(){
		hasFolded = true;
	}
	public int getBet()
	{
		int temp = currentBet;
		currentBet = 0;
		money -= temp;
		return temp;
	}

	public Hand getCurrentBestHand()
	{
		if(handUpdated || bestHand == null)
		{
			handUpdated = false;
			bestHand = calcBestHand();
			return bestHand;
		}
		else
		{
			return bestHand;
		}
	}

	public LinkedList<Hand> getCurrentHands()
	{
		return currentHands;
	}
	
	public int getEmotionalState(){
		return emotionalState;
	}
	
	public boolean getHasBet(){
		return hasBet;
	}
	
	public boolean getHasFolded(){
		return hasFolded;
	}
	
	public LinkedList<Card> getHoleCards(){
		return holeCards;
	}
	
	public int getMoney(){
		return money;
	}
	
	public String getName(){
		return name;
	}
	
	public boolean hasActed()
	{
		return hasActed;
	}
	
	public void placeBet( int d ){
		if( d > money ){
			System.out.println("You do not have that much money, all of your money is now betted");
			d = money;
		}
		money = money - d;
		currentBet = d;
		hasBet = true;
	}
	public void clearHoleCards()
	{
		for(int i=0; i<holeCards.size(); i++)
		{
			holeCards.remove();
		}
	}
	
	public void receiveCard( Card c ){
		holeCards.add(c);
		handUpdated = true;
	}
	public void setBet(int b)
	{
		currentBet = b;
	}
	
	public void receiveMoney( int m ){
		money = money + m;
	}
	public void setRaised(boolean b)
	{
		hasRaised = b;
	}
	public void setFolded(boolean b){
		hasFolded = b;
	}
	public void setHasBet(boolean b){
		hasBet = b;
	}
	public String toStringHoleCards()
	{
		String toReturn;
		if(hasFolded)
		{
			toReturn = "folded\n";
		}
		else
		{
			toReturn = holeCards.get(0).toString();
			toReturn += " and ";
			toReturn += holeCards.get(1).toString();
			toReturn += " \n";
		}
		return toReturn;
	}
	public void setNotActed()
	{
		hasActed = false;
	}
}
